{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "title: Ownership and borrowing\n",
    "sidebar_position: 3\n",
    "description: How Mojo shares references through function arguments.\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A challenge you might face when using some programming languages is that you\n",
    "must manually allocate and deallocate memory. When multiple parts of the\n",
    "program need access to the same memory, it becomes difficult to keep track of\n",
    "who \"owns\" a value and determine when is the right time to deallocate it. If\n",
    "you make a mistake, it can result in a \"use-after-free\" error, a \"double free\"\n",
    "error, or a \"leaked memory\" error, any one of which can be catastrophic.\n",
    "\n",
    "Mojo helps avoid these errors by ensuring there is only one variable that owns\n",
    "each value at a time, while still allowing you to share references with other\n",
    "functions. When the life span of the owner ends, Mojo [destroys the\n",
    "value](/mojo/manual/lifecycle/death). Programmers are still responsible for\n",
    "making sure any type that allocates resources (including memory) also\n",
    "deallocates those resources in its destructor. Mojo's ownership system ensures\n",
    "that destructors are called promptly.\n",
    "\n",
    "On this page, we'll explain the rules that govern this ownership model, and how\n",
    "to specify different argument conventions that define how values are passed into\n",
    "functions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Argument conventions\n",
    "\n",
    "In all programming languages, code quality and performance is heavily dependent\n",
    "upon how functions treat argument values. That is, whether a value received by\n",
    "a function is a unique value or a reference, and whether it's mutable or\n",
    "immutable, has a series of consequences that define the readability,\n",
    "performance, and safety of the language.\n",
    "\n",
    "In Mojo, we want to provide full [value\n",
    "semantics](/mojo/manual/values/value-semantics) by default, which provides\n",
    "consistent and predictable behavior. But as a systems programming language, we\n",
    "also need to offer full control over memory optimizations, which generally\n",
    "requires reference semantics. The trick is to introduce reference semantics in\n",
    "a way that ensures all code is memory safe by tracking the lifetime of every\n",
    "value and destroying each one at the right time (and only once). All of this is\n",
    "made possible in Mojo through the use of argument conventions that ensure every\n",
    "value has only one owner at a time.\n",
    "\n",
    "An argument convention specifies whether an argument is mutable or immutable,\n",
    "and whether the function owns the value. Each convention is defined by a\n",
    "keyword at the beginning of an argument declaration:\n",
    "\n",
    "- `borrowed`: The function receives an **immutable reference**. This means the\n",
    "  function can read the original value (it is *not* a copy), but it cannot\n",
    "  mutate (modify) it. `def` functions treat this differently, as described below.\n",
    "  \n",
    "- `inout`: The function receives a **mutable reference**. This means the\n",
    "  function can read and mutate the original value (it is *not* a copy).\n",
    "  \n",
    "- `owned`: The function takes **ownership**. This means the function has\n",
    "  exclusive ownership of the argument. Often, this also implies that the caller\n",
    "  should transfer ownership to this function, but that's not always what\n",
    "  happens and this might instead be a copy (as you'll learn below).\n",
    "\n",
    "- `ref`: The function gets a reference with an associated lifetime. The\n",
    "  reference can be either mutable or immutable. You can think of `ref` arguments\n",
    "  as a generalization of the `borrowed` and `inout` conventions. `ref` arguments\n",
    "  are an advanced topic, and they're described in more detail in [Lifetimes and \n",
    "  references](/mojo/manual/values/lifetimes).\n",
    "\n",
    "For example, this function has one argument that's a mutable\n",
    "reference and one that's immutable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "fn add(inout x: Int, borrowed y: Int):\n",
    "    x += y\n",
    "\n",
    "fn main():\n",
    "    var a = 1\n",
    "    var b = 2\n",
    "    add(a, b)\n",
    "    print(a)  # Prints 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You've probably already seen some function arguments that don't declare a\n",
    "convention. by default, all arguments are `borrowed`. But `def` and `fn` \n",
    "functions treat `borrowed` arguments somewhat differently:\n",
    "\n",
    "\n",
    "- In an [`fn` function](/mojo/manual/functions#fn-functions), the function\n",
    "  always receives an immutable reference. If you want a mutable copy, you can\n",
    "  assign it to a local variable:\n",
    "\n",
    "  ```mojo\n",
    "  var my_copy = borrowed_arg\n",
    "  ```\n",
    "\n",
    "- In a [`def` function](/mojo/manual/functions#def-functions), if the \n",
    "  function mutates the value, the function receives a mutable copy of the \n",
    "  argument. Otherwise, it receives an immutable reference. This allows you to\n",
    "  treat arguments as mutable, but avoid the overhead of making extra copies when\n",
    "  they're not needed.\n",
    "\n",
    "The difference between `borrowed` and `owned` in a `def` function may be a\n",
    "little subtle: \n",
    "\n",
    "- In a `def` function, a `borrowed` argument is received as an immutable\n",
    "  reference, unless it's mutated in the body of the function. This eliminates\n",
    "  unneeded copies, but maintains the Python expectation that arguments are \n",
    "  mutable.\n",
    "\n",
    "- The `borrowed` argument always gets an immutable reference or a local copy.\n",
    "  You can't transfer a value into a `borrowed` argument.\n",
    "\n",
    "- The `owned` argument always gets a uniquely owned value, which may have been\n",
    "  copied or transferred from the callee. Using `owned` arguments without the \n",
    "  transfer sigil (`^`) usually results in values being copied.\n",
    "\n",
    "In the following sections, we'll explain each of these argument conventions in\n",
    "more detail."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ownership summary\n",
    "\n",
    "The fundamental rules that make Mojo's ownership model work are the following:\n",
    "\n",
    "- Every value has only one owner at a time.\n",
    "- When the lifetime of the owner ends, Mojo destroys the value.\n",
    "- If there are outstanding references to a value, Mojo keeps the value alive.\n",
    "\n",
    "In the future, the Mojo lifetime checker will enforce reference exclusivity, so\n",
    "that only one mutable reference to a value can exist at a time. **This is not\n",
    "currently enforced.**\n",
    "\n",
    "<!--\n",
    "\n",
    "- You cannot create multiple mutable references (`inout`) for the same value.\n",
    "  (Multiple immutable references (`borrowed`) are okay.)\n",
    "\n",
    "- You cannot create a mutable reference (`inout`) if there exists an\n",
    "  immutable reference (`borrowed`) for the same value. (TODO: Not currently\n",
    "  implemented.)\n",
    "\n",
    "Because Mojo does not allow a mutable reference to overlap with another mutable\n",
    "or immutable reference, it provides a predictable programming model about which\n",
    "references are and aren't valid (an invalid reference is one whose lifetime has\n",
    "ended, perhaps because the value ownership was transferred). Importantly, this\n",
    "logic allows Mojo to immediately [destroy\n",
    "values](/mojo/manual/lifecycle/death) when their lifetime ends.\n",
    "\n",
    "-->"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Borrowed arguments (`borrowed`)\n",
    "\n",
    "The `borrowed` convention is the default for all arguments.\n",
    "\n",
    "In `fn` functions, a `borrowed` argument is received as an immutable reference.\n",
    "\n",
    "In `def` functions, you can treat a `borrowed` argument as mutable or immutable.\n",
    "If you mutate the argument in the body of the function, you get a mutable copy\n",
    "of the original value. If you don't mutate the argument, you get an immutable\n",
    "reference, as in an `fn` function.\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "from collections import List\n",
    "\n",
    "def print_list(list: List[Int]):\n",
    "    print(list.__str__())\n",
    "\n",
    "var list = List(1, 2, 3, 4)\n",
    "print_list(list)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here the `list` argument to `print_list()` is borrowed and not mutated, so the \n",
    "`print_list()` function gets an immutable reference to the original `List`, and\n",
    "doesn't do any copying. \n",
    "\n",
    "In general, passing an immutable reference is much more efficient\n",
    "when handling large or expensive-to-copy values, because the copy constructor\n",
    "and destructor are not invoked for a borrow.\n",
    "\n",
    "To avoid expensive copies, types should only be implicitly copyable if the copy\n",
    "operation is inexpensive.\n",
    "\n",
    "### Compared to C++ and Rust\n",
    "\n",
    "Mojo's borrowed argument convention is similar in some ways to passing an\n",
    "argument by `const&` in C++, which also avoids a copy of the value and disables\n",
    "mutability in the callee. However, the borrowed convention differs from\n",
    "`const&` in C++ in two important ways:\n",
    "\n",
    "- The Mojo compiler implements a lifetime checker that ensures that values are\n",
    "not destroyed when there are outstanding references to those values.\n",
    "\n",
    "- Small values like `Int`, `Float`, and `SIMD` are passed directly in machine\n",
    "registers instead of through an extra indirection (this is because they are\n",
    "declared with the `@register_passable` decorator). This is a [significant\n",
    "performance\n",
    "enhancement](https://www.forrestthewoods.com/blog/should-small-rust-structs-be-passed-by-copy-or-by-borrow/)\n",
    "when compared to languages like C++ and Rust, and moves this optimization from\n",
    "every call site to a declaration on the type definition.\n",
    "\n",
    "In the future, Mojo's lifetime checker will enforce the exclusivity of\n",
    "mutable references, similar to Rust.\n",
    "The major difference between Rust and Mojo is that Mojo does not require a\n",
    "sigil on the caller side to pass by borrow. Also, Mojo is more efficient when\n",
    "passing small values, and Rust defaults to moving values instead of passing\n",
    "them around by borrow. These policy and syntax decisions allow Mojo to provide\n",
    "an easier-to-use programming model."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Mutable arguments (`inout`)\n",
    "\n",
    "If you'd like your function to receive a **mutable reference**, add the `inout`\n",
    "keyword in front of the argument name. You can think of `inout` like this: it\n",
    "means any changes to the value *in*side the function are visible *out*side the\n",
    "function.\n",
    "\n",
    "For example, this `mutate()` function updates the original `list` value:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "from collections import List\n",
    "\n",
    "def mutate(inout l: List[Int]):\n",
    "    l.append(5)\n",
    "\n",
    "var list = List(1, 2, 3, 4)\n",
    "\n",
    "mutate(list)\n",
    "print_list(list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That behaves like an optimized replacement for this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "from collections import List\n",
    "\n",
    "def mutate_copy(l: List[Int]) -> List[Int]:\n",
    "    l.append(5)\n",
    "    return l\n",
    "\n",
    "var list = List(1, 2, 3, 4)\n",
    "list = mutate_copy(list)\n",
    "print_list(list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Although the code using `inout` isn't that much shorter, it's more memory\n",
    "efficient because it does not make a copy of the value.\n",
    "\n",
    "However, remember that the values passed as `inout` must already be mutable.\n",
    "For example, if you try to take a `borrowed` value and pass it to another\n",
    "function as `inout`, you'll get a compiler error because Mojo can't form a\n",
    "mutable reference from an immutable reference.\n",
    "\n",
    ":::note\n",
    "\n",
    "You cannot define [default\n",
    "values](/mojo/manual/functions#optional-arguments) for `inout`\n",
    "arguments.\n",
    "\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Argument exclusivity\n",
    "\n",
    "Mojo enforces _argument exclusivity_ for mutable references. This means that if\n",
    "a function receives a mutable reference to a value (such as an `inout` argument),\n",
    "it can't receive any other references to the same value—mutable or immutable.\n",
    "That is, a mutable reference can't have any other references that _alias_ it.\n",
    "\n",
    "For example, consider the following code example:\n",
    "\n",
    "```mojo\n",
    "fn append_twice(inout s: String, other: String):\n",
    "   # Mojo knows 's' and 'other' cannot be the same string.\n",
    "   s += other\n",
    "   s += other\n",
    "\n",
    "fn invalid_access():\n",
    "  var my_string = str(\"o\")\n",
    "\n",
    "  # warning: passing `my_string` inout is invalid since it is also passed\n",
    "  # borrowed.\n",
    "  append_twice(my_string, my_string)\n",
    "  print(my_string)\n",
    "```\n",
    "\n",
    "This code is confusing because the user might expect the output to be `ooo`, \n",
    "but since the first addition mutates both `s` and `other`, the actual output\n",
    "would be `oooo`. Enforcing exclusivity of mutable references not only prevents\n",
    "coding errors, it also allows the Mojo compiler to optimize code in some cases.\n",
    "\n",
    "One way to avoid this issue when you do need both a mutable and an immutable \n",
    "reference (or need to pass the same value to two arguments) is to make a copy:\n",
    "\n",
    "```mojo\n",
    "fn valid_access():\n",
    "  var my_string = str(\"o\")\n",
    "  var other_string = str(my_string)\n",
    "  append_twice(my_string, other_string)\n",
    "  print(my_string)\n",
    "```\n",
    "\n",
    ":::note Only a warning\n",
    "\n",
    "Aliasing a mutable reference produces a warning in v24.5. This will change to an\n",
    "error in a subsequent release.\n",
    "\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transfer arguments (`owned` and `^`)\n",
    "\n",
    "And finally, if you'd like your function to receive value **ownership**, add the\n",
    "`owned` keyword in front of the argument name.\n",
    "\n",
    "This convention is often combined with use of the postfixed `^` \"transfer\"\n",
    "sigil on the variable that is passed into the function, which ends the\n",
    "lifetime of that variable.\n",
    "\n",
    "Technically, the `owned` keyword does not guarantee that the received value is\n",
    "_the original value_—it guarantees only that the function\n",
    "gets unique ownership of a value. This happens in one of\n",
    "three ways:\n",
    "\n",
    "- The caller passes the argument with the `^` transfer sigil, which ends the\n",
    "lifetime of that variable (the variable becomes uninitialized) and ownership is\n",
    "transferred into the function without making a copy of any heap-allocated data.\n",
    "\n",
    "- The caller **does not** use the `^` transfer sigil, in which case, the\n",
    "value is copied into the function argument and the original variable remains\n",
    "valid. (If the original value is not used again, the compiler may optimize away\n",
    "the copy and transfer the value).\n",
    "\n",
    "- The caller passes in a newly-created \"owned\" value, such as a value returned\n",
    "from a function. In this case, no variable owns the value and it can be\n",
    "transferred directly to the callee. For example:\n",
    "\n",
    "  ```mojo\n",
    "  def take(owned s: String):\n",
    "      pass\n",
    "\n",
    "  take(str(\"A brand-new String!\"))\n",
    "  ```\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, the following code works by making a copy of the string,\n",
    "because—although `take_text()` uses the `owned` convention—the caller does not\n",
    "include the transfer sigil:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello!\n",
      "Hello\n"
     ]
    }
   ],
   "source": [
    "fn take_text(owned text: String):\n",
    "    text += \"!\"\n",
    "    print(text)\n",
    "\n",
    "fn my_function():\n",
    "    var message: String = \"Hello\"\n",
    "    take_text(message)\n",
    "    print(message)\n",
    "\n",
    "my_function()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, if you add the `^` transfer sigil when calling `take_text()`, the\n",
    "compiler complains about `print(message)`, because at that point, the `message`\n",
    "variable is no longer initialized. That is, this version does not compile:\n",
    "\n",
    "```mojo\n",
    "fn my_function():\n",
    "    var message: String = \"Hello\"\n",
    "    take_text(message^)  \n",
    "    print(message)  # ERROR: The `message` variable is uninitialized\n",
    "```\n",
    "\n",
    "This is a critical feature of Mojo's lifetime checker, because it ensures that no\n",
    "two variables can have ownership of the same value. To fix the error, you must\n",
    "not use the `message` variable after you end its lifetime with the `^` transfer\n",
    "operator. So here is the corrected code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello!\n"
     ]
    }
   ],
   "source": [
    "\n",
    "fn my_function():\n",
    "    var message: String = \"Hello\"\n",
    "    take_text(message^)\n",
    "\n",
    "my_function()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Regardless of how it receives the value, when the function declares an argument\n",
    "as `owned`, it can be certain that it has unique mutable access to that value. \n",
    "Because the value is owned, the value is destroyed when the function \n",
    "exits—unless the function transfers the value elsewhere.\n",
    "\n",
    "For example, in the following example, `add_to_list()` takes a string and\n",
    "appends it to the list. Ownership of the string is transferred to the list, so\n",
    "it's not destroyed when the function exits. On the other hand, \n",
    "`consume_string()` doesn't transfer its `owned` value out, so the value is \n",
    "destroyed at the end of the function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import List\n",
    "\n",
    "def add_to_list(owned name: String, inout list: List[String]):\n",
    "    list.append(name^)\n",
    "    # name is uninitialized, nothing to destroy\n",
    "\n",
    "def consume_string(owned s: String):\n",
    "    print(s)\n",
    "    # s is destroyed here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::note\n",
    "\n",
    "Value lifetimes are not fully implemented for top-level code in\n",
    "Mojo's REPL, so the transfer sigil currently works as intended only when\n",
    "used inside a function.\n",
    "\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Transfer implementation details\n",
    "\n",
    "In Mojo, you shouldn't conflate \"ownership transfer\" with a \"move\n",
    "operation\"—these are not strictly the same thing. \n",
    "\n",
    "There are multiple ways that Mojo can transfer ownership of a value:\n",
    "\n",
    "- If a type implements the [move\n",
    "  constructor](/mojo/manual/lifecycle/life#move-constructor),\n",
    "  `__moveinit__()`, Mojo may invoke this method _if_ a value of that type is\n",
    "  transferred into a function as an `owned` argument, _and_ the original\n",
    "  variable's lifetime ends at the same point (with or without use of the `^`\n",
    "  transfer operator).\n",
    "\n",
    "- If a type implements the [copy \n",
    "  constructor](/mojo/manual/lifecycle/life#move-constructor), `__copyinit__()`\n",
    "  and not `__moveinit__()`, Mojo may copy the value and destroy the old value.\n",
    "\n",
    "- In some cases, Mojo can optimize away the move operation entirely, leaving the \n",
    "  value in the same memory location but updating its ownership. In these cases,\n",
    "  a value can be transferred without invoking either the `__copyinit__()` or \n",
    "  `__moveinit__()` constructors.\n",
    "\n",
    "In order for the `owned` convention to work _without_ the transfer\n",
    "sigil, the value type must be copyable (via `__copyinit__()`)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comparing `def` and `fn` argument conventions\n",
    "\n",
    "As mentioned in the section about\n",
    "[functions](/mojo/manual/functions), `def` and `fn` functions\n",
    "are interchangeable, as far as a caller is concerned, and they can both\n",
    "accomplish the same things. It's only the inside that differs, and Mojo's `def`\n",
    "function is essentially just sugaring for the `fn` function:\n",
    "\n",
    "- A `def` argument without a type annotation defaults to\n",
    "  [`object`](/mojo/stdlib/builtin/object/object) type (whereas as `fn`\n",
    "  requires all types be explicitly declared).\n",
    "\n",
    "- A `def` function can treat a `borrowed` argument as mutable (in which case it\n",
    "  receives a mutable copy). An `fn` function must make this copy explicitly.\n",
    "\n",
    "For example, these two functions have the exact same behavior."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "def def_example(a: Int, inout b: Int, owned c):\n",
    "    pass\n",
    "\n",
    "fn fn_example(a_in: Int, inout b: Int, owned c: object):\n",
    "    var a = a_in\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This shadow copy typically adds no overhead, because small types\n",
    "like `object` are cheap to copy. However, copying large types that allocate heap\n",
    "storage can be expensive. (For example, copying `List` or `Dict` types, or\n",
    "copying large numbers of strings.)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Mojo",
   "language": "mojo",
   "name": "mojo-jupyter-kernel"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "mojo"
   },
   "file_extension": ".mojo",
   "mimetype": "text/x-mojo",
   "name": "mojo"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
